package com.zuo;

/*
*我们已经知道，Java的数据类型分两种：
* 基本类型：byte，short，int，long，boolean，float，double，char
* 引用类型：所有class和interface类型
* 引用类型可以赋值为null，表示空，但基本类型不能赋值为null：
* String s = null;
* int n = null; // compile error!
*
* 那么，如何把一个基本类型视为对象（引用类型）？
* 比如，想要把int基本类型变成一个引用类型，我们可以定义一个Integer类，它只包含一个实例字段int，这样，Integer类就可以视为int的包装类（Wrapper Class）：
*
* 因为包装类性用处很多,所以Java核心类库为每种基本类型都提供了对应的包装类型
* boolean	java.lang.Boolean
* byte	    java.lang.Byte
* short	    java.lang.Short
* int	    java.lang.Integer
* long	    java.lang.Long
* float	    java.lang.Float
* double	java.lang.Double
* char	    java.lang.Character
* 我们可以直接使用Java提供的包装类型,而不用自己去定义
*
 *  */
public class PackagingTypeZuo {

    public static void main(String[] args) {
//       1: 使用我们自定义的int基本类的包装类型
        //    我们可以把int和Interer相互转换
        Integer i = null;
        Integer i1 = new Integer(99);
        int i2 = i1.intValue();

        System.out.println(i);//null
        System.out.println(i1.intValue());//99
        System.out.println(i2);//99

//       2: 使用系统提供的基本类型的包装类型
        int i3 = 100;
//        (1):通过new操作符创建Integer实例(不推荐使用,会有编译警告)
        java.lang.Integer n1 = new java.lang.Integer(i3);
//        (2):通过静态方法valueOf(int)创建Integer实例
        java.lang.Integer n2 = java.lang.Integer.valueOf(i3);
//        (3):通过静态方法valueOf(String)创建的Integer实例
        java.lang.Integer n3 = java.lang.Integer.valueOf("100");

        System.out.println(n1);//100
        System.out.println(n2);//100
        System.out.println(n3);//100

//        3:因为int和Integer可以互相转换
        int i4 = 100;
        java.lang.Integer n4 = java.lang.Integer.valueOf(i4);
        int i5 = n4.intValue();
//        所以Java编译器可以帮助我们自动在int 和 Integer之间转换
        java.lang.Integer n5 = 100;
        int i6 = n5;

        System.out.println("n5 = " + n5);
        System.out.println("i6 = " + i6);
//      这种直接把int变为Integer的赋值写法,成为自动装箱,反过来,把Intege变为int的赋值写法,称为自动拆箱
//      注:自动装箱和自动拆箱只发生在编译阶段,目的是为了少些代码

//        4:不变类
//        所有的包装类都是不可变的,因此一旦创建了包装类对象,该对象就是不变的

//        5:进制转换
//        Integer还可以把整数格式化为制定进制的字符串
        System.out.println(java.lang.Integer.toString(100));//100  十进制
        System.out.println(java.lang.Integer.toString(100,36));// 2s   36进制
        System.out.println(java.lang.Integer.toHexString(100));//64    16进制
        System.out.println(java.lang.Integer.toOctalString(100));//144  8进制
        System.out.println(java.lang.Integer.toBinaryString(100));//1100100   2进制

//        6:所有的整数和浮点数的包装类型都继承自Number,因此可以非常方便的直接通过包装额理性获取各种基本类型
//        把Integer向上转型为Number
        Number num = new java.lang.Integer(999);

//        获取byte,int,long,float,double
        byte b = num.byteValue();
        int n = num.intValue();
        long ln = num.longValue();
        float f = num.floatValue();
        double d = num.doubleValue();

        System.out.println(b);
        System.out.println(n);
        System.out.println(ln);
        System.out.println(f);
        System.out.println(d);

//        7:无符号整型
//        在Java中，并没有无符号整型（Unsigned）的基本数据类型。byte、short、int和long都是带符号整型，最高位是符号位。而C语言则提供了CPU支持的全部数据类型，包括无符号整型。无符号整型和有符号整型的转换在Java中就需要借助包装类型的静态方法完成。
//        例如，byte是有符号整型，范围是-128~+127，但如果把byte看作无符号整型，它的范围就是0~255。我们把一个负的byte按无符号整型转换为int：
        byte x = -1;
        byte y = 127;
        System.out.println(Byte.toUnsignedInt(x));//因为byte的-1的二进制表示是11111111，以无符号整型转换后的int就是255。
        System.out.println(Byte.toUnsignedInt(y));//127

    }
}

/*
* 定义一个int 类型的包装类 Integer
* */
class Integer {
    private int value;
    public Integer(int value){
        this.value = value;
    }
    public int intValue(){
        return this.value;
    }
}